import 'dart:convert';

import 'package:chatgreat/bloc/bloc_manager.dart';
import 'package:chatgreat/helper/queue.dart';
import 'package:chatgreat/repo/api/creative.dart';
import 'package:chatgreat/repo/api_server.dart';
import 'package:chatgreat/repo/creative_island_repo.dart';
import 'package:dart_openai/openai.dart';
import 'package:flutter/material.dart';

import '../helper/logger.dart';
import '../repo/model/message.dart';
import '../repo/openai_repo.dart';

part 'creative_island_event.dart';
part 'creative_island_state.dart';

class CreativeIslandBloc
    extends BlocExt<CreativeIslandEvent, CreativeIslandState> {
  final CreativeIslandRepository creativeIslandRepo;
  GracefulQueue<ChatStreamRespData>? currentQueue;

  CreativeIslandBloc(this.creativeIslandRepo) : super(CreativeIslandInitial()) {
    on<CreativeIslandItemsV2LoadEvent>((event, emit) async {
      final items =
          await APIServer().creativeIslandItemsV2(cache: !event.forceRefresh);
      emit(CreativeIslandItemsWorkLoaded(
        items: items,
      ));
    });

    on<CreateGenerateContentLoadEvent>((event, emit) async {

      emit(CreateGenerateContentIsReadyLoaded(isReady: false));

      var message = CreateMessage('');
      message.newText = [];
      // 等待监听机器人应答消息
      final queue = GracefulQueue<ChatStreamRespData>();
      currentQueue = queue;
      try {
        RequestFailedException? error;
        try {
          var listener =
              queue.listen(const Duration(milliseconds: 10), (items) {
            final systemCmds = items.where((e) => e.role == 'system').toList();

            if (systemCmds.isNotEmpty) {
              for (var element in systemCmds) {
                try {
                  if (element.content.contains('id')) {
                    var map = jsonDecode(element.content);
                    print('------------------ sunyi jsonstr: $map');
                    message.id = map['id'];
                  }
                } catch (e) {
                  // ignore: avoid_print
                  print('Error decoding the JSON string: $e');
                }
              }
            }

            var content = systemCmds.map((e) => e.content).join('');
            if (!content.contains('id')) {
              message.text += content;
              message.newText?.add(content);
            }
            emit(CreateGenerateContentWorkLoaded(message, processing: true));

            // 失败处理
            for (var e in items) {
              if (e.code != null && e.code! > 0) {
                error = RequestFailedException(e.error ?? '请求处理失败', e.code!);
              }
            }
          });

          // 开始生成
          await APIServer()
              .startCreate(event.itemId, event.content, queue.add)
              .whenComplete(queue.finish);

          await listener;

          message.text = message.text.trim();
          if (message.text.isEmpty) {
            error = RequestFailedException('AI没有回答任何内容', 500);
          }

          if (error != null) {
            throw error!;
          }
        } catch (e) {
          if (message.text.isEmpty) {
            Logger.instance.e('响应过程中出错了: $e');
            rethrow;
          }
        }

        // AI应答完成，替换掉思考中消息
        emit(CreateGenerateContentIsReadyLoaded(isReady: true));
      } catch (e) {


        // emit(ChatMessagesLoaded(
        //   await chatMsgRepo.getRecentMessages(
        //     roomId,
        //     userId: APIServer().localUserID(),
        //     chatHistoryId: localChatHistoryId,
        //   ),
        //   error: error,
        //   chatHistory: localChatHistory,
        // ));

        queue.finish();
      } finally {
        queue.dispose();
        currentQueue = null;
      }

      emit(CreateGenerateContentWorkLoaded(message));
    });

    on<CreativeIslandItemLoadEvent>((event, emit) async {
      final resp = await APIServer().creativeIslandItem(event.itemId);
      emit(CreativeIslandItemLoaded(resp));
    });

    on<CreativeIslandHistoriesAllLoadEvent>((event, emit) async {
      emit(CreativeIslandHistoriesLoading());

      final items = await APIServer()
          .creativeHistories(cache: !event.forceRefresh, mode: event.mode);
      emit(CreativeIslandHistoriesAllLoaded(items.data));
    });

    on<CreativeIslandGalleryLoadEvent>((event, emit) async {
      emit(CreativeIslandHistoriesLoading());

      final items = await APIServer().creativeUserGallery(
          cache: false, mode: event.mode, model: event.model);
      emit(CreativeIslandGalleryLoaded(items));
    });

    on<CreativeIslandHistoriesLoadEvent>((event, emit) async {
      emit(CreativeIslandHistoriesLoading());
      final island = await APIServer().creativeIslandItem(event.itemId);

      emit(CreativeIslandHistoriesLoaded(
        island,
        await APIServer().creativeItemHistories(
          island.id,
          cache: !event.forceRefresh,
        ),
      ));
    });

    on<CreativeIslandDeleteEvent>((event, emit) async {
      emit(CreativeIslandHistoriesLoading());
      await APIServer()
          .deleteCreativeHistoryItem(event.itemId, hisId: event.id);

      if (event.source == 'all-histories') {
        final res =
            await APIServer().creativeHistories(cache: false, mode: event.mode);
        emit(CreativeIslandHistoriesAllLoaded(res.data));
      } else {
        final island = await APIServer().creativeIslandItem(event.itemId);
        emit(CreativeIslandHistoriesLoaded(
          island,
          await APIServer().creativeItemHistories(
            island.id,
            cache: false,
          ),
        ));
      }
    });

    on<CreativeIslandListLoadEvent>((event, emit) async {
      emit(CreativeIslandInitial());

      try {
        final items = await APIServer().creativeIslandItems(mode: event.mode);

        emit(CreativeIslandListLoaded(
          items.items,
          categories: items.categories,
          backgroundImage: items.backgroundImage,
        ));
      } catch (e) {
        emit(
            CreativeIslandListLoaded(const [], error: e, categories: const []));
      }
    });

    on<CreativeIslandHistoryItemLoadEvent>((event, emit) async {
      emit(CreativeIslandHistoryItemLoading());
      emit(CreativeIslandHistoryItemLoaded(
        item: await APIServer().creativeHistoryItem(
          hisId: event.itemId,
          cache: !event.forceRefresh,
        ),
      ));
    });
  }
}
